#include "UtilityPCH.h"
#include "UT_GeometryTriangleMesh.h"
#include "UT_GeometryTriangle.h"
#include "UT_MathHelper.h"

using namespace Utility;

//-------------------------------------------------------------------
UT_GeometryTriangleMesh::UT_GeometryTriangleMesh(const UT_Transform *o2w, const UT_Transform *w2o, bool bReverseOrientation, 
	int32_t iTriangleNum,int32_t iVertexNum, 
	const int32_t* piIndices, const UT_Point3Float* pkVertices,
	const UT_Normal3Float* pkNormals,const UT_Vec3Float* pkTangents, 
	const float* pfUV,const UT_SmartPointer<UT_Texture<float>>& spAlphaTex)
	: UT_GeometryBase(o2w,w2o,bReverseOrientation)
{
	m_iTriangleNum = iTriangleNum;
	m_iVertexNum   = iVertexNum;
	m_piIndices	   = MM_NEW int32_t[3 * m_iTriangleNum];
	MEMCPY(m_piIndices,piIndices,3 * m_iTriangleNum * sizeof(int32_t));

	if(pfUV)
	{
		m_pfUVs = MM_NEW float[2 * m_iVertexNum];
		MEMCPY(m_pfUVs,pfUV,2 * m_iVertexNum * sizeof(float));
	}
	else
		m_pfUVs = NULL;

	if(pkNormals)
	{
		m_pkNormals = MM_NEW UT_Normal3Float[m_iVertexNum];
		MEMCPY(m_pkNormals,pkNormals,m_iVertexNum * sizeof(UT_Normal3Float));
	}
	else
		m_pkNormals = NULL;

	if(pkTangents)
	{
		m_pkTangents = MM_NEW UT_Vec3Float[m_iVertexNum];
		MEMCPY(m_pkTangents,pkTangents,m_iVertexNum * sizeof(UT_Vec3Float));
	}
	else
		m_pkTangents = NULL;

	for(int32_t i = 0; i < m_iVertexNum; i++)
		m_pkVetices[i] = (*m_pkObjectToWorld)(pkVertices[i]);
}
//-------------------------------------------------------------------
UT_GeometryTriangleMesh::~UT_GeometryTriangleMesh() 
{
	MM_DELETE[] m_piIndices;
	MM_DELETE[] m_pkVetices;
	MM_DELETE[] m_pkTangents;
	MM_DELETE[] m_pkNormals;
	MM_DELETE[] m_pfUVs;
}
//-------------------------------------------------------------------
UT_BBOX_AABB UT_GeometryTriangleMesh::GetObjectBound() const 
{
	UT_BBOX_AABB objectBounds;
	for (int32_t i = 0; i < m_iVertexNum; i++)
		objectBounds = UT_MathHelper::Union(objectBounds, (*m_pkWorldToObject)(m_pkVetices[i]));
	return objectBounds;
}
//-------------------------------------------------------------------
UT_BBOX_AABB UT_GeometryTriangleMesh::GetWorldBound() const 
{
	UT_BBOX_AABB worldBounds;
	for (int32_t i = 0; i < m_iVertexNum; i++)
		worldBounds = UT_MathHelper::Union(worldBounds, m_pkVetices[i]);
	return worldBounds;
}

//-------------------------------------------------------------------
void UT_GeometryTriangleMesh::Refine(UT_TVector<UT_SmartPointer<UT_GeometryBase>>& rkRefinedVector) const 
{
	for (int32_t i = 0; i < m_iTriangleNum; ++i)
	{
		rkRefinedVector.AddLast(MM_NEW UT_GeometryTriangle(m_pkObjectToWorld, 
			m_pkWorldToObject, m_bReverseOrientation,this,i));
	}
}
//-------------------------------------------------------------------
//-------------------------------------------------------------------
